package com.yeskery.nut.extend.jdbc;

/**
 * 列名策略工具类
 * @author YESKERY
 * 2024/10/9
 */
public class ColumnNameStrategies {

    /**
     * 原始字段名策略
     * @return 原始字段名策略
     */
    public static ColumnNameStrategy toOriginalCase() {
        return fieldName -> fieldName;
    }

    /**
     * 大写字段名策略
     * @return 大写字段名策略
     */
    public static ColumnNameStrategy toUpperCase() {
            return String::toUpperCase;
    };

    /**
     * 小写字段名策略
     * @return 小写字段名策略
     */
    public static ColumnNameStrategy toLowerCase() {
        return String::toLowerCase;
    }

    /**
     * 驼峰转蛇形命名字段名策略
     * @return 驼峰转蛇形命名字段名策略
     */
    public static ColumnNameStrategy camelToSnakeCase() {
        return fieldName -> {
            if (fieldName == null || fieldName.isEmpty()) {
                return fieldName;
            }

            StringBuilder snakeCase = new StringBuilder();
            for (int i = 0; i < fieldName.length(); i++) {
                char c = fieldName.charAt(i);
                if (Character.isUpperCase(c)) {
                    if (i != 0) {
                        snakeCase.append('_');
                    }
                    snakeCase.append(Character.toLowerCase(c));
                } else {
                    snakeCase.append(c);
                }
            }
            return snakeCase.toString();
        };
    }

    /**
     * 蛇形转驼峰命名字段名策略
     * @return 蛇形转驼峰命名字段名策略
     */
    public static ColumnNameStrategy snakeToCamelCase() {
        return fieldName -> {
            if (fieldName == null || fieldName.isEmpty()) {
                return fieldName;
            }

            if (fieldName.startsWith("_")) {
                fieldName = fieldName.substring(1);
            }

            StringBuilder camelCase = new StringBuilder();
            boolean capitalizeNext = false;

            for (int i = 0; i < fieldName.length(); i++) {
                char c = fieldName.charAt(i);
                if (c == '_') {
                    capitalizeNext = true;
                } else {
                    if (capitalizeNext) {
                        camelCase.append(Character.toUpperCase(c));
                        capitalizeNext = false;
                    } else {
                        camelCase.append(c);
                    }
                }
            }
            return camelCase.toString();
        };
    }

    /**
     * 帕斯卡转蛇形命名字段名策略
     * @return 帕斯卡转蛇形命名字段名策略
     */
    public static ColumnNameStrategy pascalToSnakeCase() {
        return fieldName -> {
            if (fieldName == null || fieldName.isEmpty()) {
                return fieldName;
            }

            StringBuilder snakeCase = new StringBuilder();
            boolean isFirstUpperCase = false;
            for (int i = 0; i < fieldName.length(); i++) {
                char c = fieldName.charAt(i);
                if (Character.isUpperCase(c)) {
                    if (!isFirstUpperCase) {
                        snakeCase.append(Character.toLowerCase(c));
                        isFirstUpperCase = true;
                    } else {
                        snakeCase.append('_');
                        snakeCase.append(Character.toLowerCase(c));
                    }
                } else {
                    snakeCase.append(c);
                }
            }
            return snakeCase.toString();
        };
    }

    /**
     * 蛇形转帕斯卡命名字段名策略
     * @return 蛇形转帕斯卡命名字段名策略
     */
    public static ColumnNameStrategy snakeToPascalCase() {
        return fieldName -> {
            String columnName = snakeToCamelCase().getColumnName(fieldName);
            return Character.toUpperCase(columnName.charAt(0)) + columnName.substring(1);
        };
    }

    /**
     * 驼峰转大写蛇形命名字段名策略
     * @return 驼峰转大写蛇形命名字段名策略
     */
    public static ColumnNameStrategy camelToUpperSnakeCase() {
        return fieldName -> camelToSnakeCase().getColumnName(fieldName).toUpperCase();
    }

    /**
     * 驼峰转小写蛇形命名字段名策略
     * @return 驼峰转小写蛇形命名字段名策略
     */
    public static ColumnNameStrategy camelToLowerSnakeCase() {
        return fieldName -> camelToSnakeCase().getColumnName(fieldName).toLowerCase();
    }
}
